use sqlx::SqlitePool;
use anyhow::Result;
use chrono::Utc;
use uuid::Uuid;

use super::models::{Account, Platform, Tab, Session};

pub struct AccountRepository;

impl AccountRepository {
    pub async fn create(pool: &SqlitePool, account: &Account) -> Result<()> {
        sqlx::query!(
            r#"
            INSERT INTO accounts (id, platform, username, password, status, last_active, created_at, cookies, notes)
            VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
            "#,
            account.id,
            account.platform,
            account.username,
            account.password,
            account.status,
            account.last_active,
            account.created_at,
            account.cookies,
            account.notes
        ).execute(pool).await?;
        Ok(())
    }

    pub async fn get_all(pool: &SqlitePool) -> Result<Vec<Account>> {
        let accounts = sqlx::query_as!(Account,
            "SELECT * FROM accounts ORDER BY created_at DESC"
        ).fetch_all(pool).await?;
        Ok(accounts)
    }

    pub async fn get_by_id(pool: &SqlitePool, id: &str) -> Result<Option<Account>> {
        let account = sqlx::query_as!(Account,
            "SELECT * FROM accounts WHERE id = ?",
            id
        ).fetch_optional(pool).await?;
        Ok(account)
    }

    pub async fn update_status(pool: &SqlitePool, id: &str, status: &str) -> Result<()> {
        sqlx::query!(
            "UPDATE accounts SET status = ?, last_active = ? WHERE id = ?",
            status,
            Utc::now(),
            id
        ).execute(pool).await?;
        Ok(())
    }

    pub async fn delete(pool: &SqlitePool, id: &str) -> Result<()> {
        sqlx::query!(
            "DELETE FROM accounts WHERE id = ?",
            id
        ).execute(pool).await?;
        Ok(())
    }
}

pub struct PlatformRepository;

impl PlatformRepository {
    pub async fn create(pool: &SqlitePool, platform: &Platform) -> Result<()> {
        sqlx::query!(
            r#"
            INSERT INTO platforms (id, name, logo, login_url, url_pattern, dom_selector, api_endpoint, is_enabled, created_at)
            VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
            "#,
            platform.id,
            platform.name,
            platform.logo,
            platform.login_url,
            platform.url_pattern,
            platform.dom_selector,
            platform.api_endpoint,
            platform.is_enabled,
            platform.created_at
        ).execute(pool).await?;
        Ok(())
    }

    pub async fn get_all(pool: &SqlitePool) -> Result<Vec<Platform>> {
        let platforms = sqlx::query_as!(Platform,
            "SELECT * FROM platforms ORDER BY name"
        ).fetch_all(pool).await?;
        Ok(platforms)
    }
}

pub struct TabRepository;

impl TabRepository {
    pub async fn create(pool: &SqlitePool, tab: &Tab) -> Result<()> {
        sqlx::query!(
            r#"
            INSERT INTO tabs (id, title, url, account_id, is_active, favicon, created_at)
            VALUES (?, ?, ?, ?, ?, ?, ?)
            "#,
            tab.id,
            tab.title,
            tab.url,
            tab.account_id,
            tab.is_active,
            tab.favicon,
            tab.created_at
        ).execute(pool).await?;
        Ok(())
    }

    pub async fn get_all(pool: &SqlitePool) -> Result<Vec<Tab>> {
        let tabs = sqlx::query_as!(Tab,
            "SELECT * FROM tabs ORDER BY created_at DESC"
        ).fetch_all(pool).await?;
        Ok(tabs)
    }

    pub async fn set_active(pool: &SqlitePool, id: &str) -> Result<()> {
        sqlx::query!(
            "UPDATE tabs SET is_active = false"
        ).execute(pool).await?;
        
        sqlx::query!(
            "UPDATE tabs SET is_active = true WHERE id = ?",
            id
        ).execute(pool).await?;
        Ok(())
    }

    pub async fn delete(pool: &SqlitePool, id: &str) -> Result<()> {
        sqlx::query!(
            "DELETE FROM tabs WHERE id = ?",
            id
        ).execute(pool).await?;
        Ok(())
    }
}